package com.ruoyi.utils;

import java.io.StringReader;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.ruoyi.utils.config.WeChatConfig;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class WeChatPayUtil {

    // 生成随机字符串
    public static String generateNonceStr() {
        System.out.println("generateNonceStr");
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    // 生成签名
    public static String generateSign(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        params.entrySet().stream()
                .filter(entry -> entry.getValue() != null && !entry.getValue().isEmpty() && !entry.getKey().equals("sign"))
                .sorted(Map.Entry.comparingByKey())
                .forEach(entry -> sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"));
        sb.append("key=").append(WeChatConfig.API_KEY);
        return MD5(sb.toString()).toUpperCase();
    }

    // MD5加密方法
    public static String MD5(String s) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(s.getBytes("UTF-8"));
            StringBuilder sign = new StringBuilder();
            for (byte b : bytes) {
                String hex = Integer.toHexString((b & 0xff) | 0x100).substring(1, 3);
                sign.append(hex);
            }
            return sign.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5加密异常", e);
        }
    }

    // 发送HTTP POST请求
    public static String post(String url, String xml) {
        try {
            HttpClient client = HttpClientBuilder.create().build();
            HttpPost post = new HttpPost(url);
            post.setHeader("Content-Type", "text/xml");
            StringEntity entity = new StringEntity(xml, "UTF-8");
            post.setEntity(entity);
            HttpResponse response = client.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            throw new RuntimeException("发送HTTP POST请求异常", e);
        }
        return null;
    }

    // XML转Map
    public static Map<String, String> parseXML(String xml) {
        try {
            Map<String, String> map = new HashMap<>();
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(xml));
            Document document = db.parse(is);
            NodeList allNodes = document.getFirstChild().getChildNodes();
            for (int i = 0; i < allNodes.getLength(); i++) {
                Node node = allNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    map.put(node.getNodeName(), node.getTextContent());
                }
            }
            return map;
        } catch (Exception e) {
            throw new RuntimeException("解析XML异常", e);
        }
    }

    // 验证签名
    public static boolean validateSign(Map<String, String> params) {
        String sign = params.get("sign");
        params.remove("sign");
        String generatedSign = generateSign(params);
        return generatedSign.equals(sign);
    }
}